package edu.mtu.citizenscience.mushroommapper.activity.main;

import java.util.Calendar;

import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import edu.mtu.citizenscience.cs.utils.exceptions.GPSNotAvailable;
import edu.mtu.citizenscience.cs.utils.gps.CitsciGPS;
import edu.mtu.citizenscience.cs.utils.gps.CitsciGPSRequest;
import edu.mtu.citizenscience.mushroommapper.MMActivity;
import edu.mtu.citizenscience.mushroommapper.activity.R;
import edu.mtu.citizenscience.mushroommapper.activity.main.find.LocationDialog;
import edu.mtu.citizenscience.mushroommapper.activity.main.find.NameSelectActivity;
import edu.mtu.citizenscience.mushroommapper.activity.main.find.PhotoActivity;
import edu.mtu.citizenscience.mushroommapper.model.ModelFamily;
import edu.mtu.citizenscience.mushroommapper.model.ModelReport;
import edu.mtu.citizenscience.mushroommapper.model.family.ModelGenus;
import edu.mtu.citizenscience.mushroommapper.model.family.genus.ModelSpecies;
import edu.mtu.citizenscience.mushroommapper.model.report.ModelImage;
/**
 * @author Corbin Uselton <corbinu@cwuselto@mtu.edu>
 * @copyright (c) 2012 MichiganTech <http://www.mtu.edu>
 * @since 1.0
 * 
 * Find Activity Responsible for recording a new mushroom find
 */
public class FindActivity extends MMActivity {
	// reference var for passing family name between activities
	public static final String FAMILY_NAME = "FAMILY_NAME";
	// reference var for passing genus name between activities
	public static final String GENUS_NAME = "GENUS_NAME";
	// reference var for passing species name between activities
	public static final String SPECIES_NAME = "SPECIES_NAME";
	
	// reference vars for result types from name select activity
	public static final int RESULT_TYPE_FAMILY = 1;
	public static final int RESULT_TYPE_GENUS = 2;
	public static final int RESULT_TYPE_SPECIES = 3;
	
	// referance vars for return types form photo activity
	public static final int RESULT_TYPE_IMAGE_GET = 4;
	public static final int RESULT_TYPE_IMAGE_DELETE = 5;
	
	// object for interacting with GPSService to get the current location
	private CitsciGPS gps = new CitsciGPS();
	
	// dialog to display when waiting to get the find location
	private LocationDialog locationDialog = new LocationDialog();
	
	// Model which holds the data for this report
	private ModelReport report;
	
	// Models which hold the photos for this report
	private ModelImage photoOne;
	private ModelImage photoTwo;
	private ModelImage photoThree;
	
	// String for the name of the mushroom found
	private String family = "Unknown";
	private String genus = "Unknown";
	private String species = "Unknown";
	
	/**
	 * @since 1.0
	 * 
	 * Handles result from a location request to the GPS service
	 */
	private class LocationRequest implements CitsciGPSRequest {

		/**
		 * Called by the CitsciGPS when it has a location
		 * 
		 * @param location - Location - the current location from the GPS
		 * @return void
		 */
		public void locationResult(Location location) 
		{
			Log.d("Find", "Got location from time: " + location.getTime());	
			// save the new location to the report
			saveLocation(location);
		}

	}

	/**
	 * Find Activity creation handler
	 * 
	 * @param   savedInstanceState - Bundle - Bundle with launch info
	 * @return	void
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        
        this.setContentView(R.layout.find_activity);
        
        // try to get the report id from the intent bundle incase we are editing a previous find
        long reportId = this.getIntent().getLongExtra(ModelReport.REPORT_ID, -1);
        
        // check to see if we got a report id
        if (reportId > -1)
		{
        	// set the report model to the model with the given report id
			this.report = new ModelReport(this, reportId);
			
			// check if the report model has a photo one model attached
			if (this.report.getPhotoOne().getId() > -1)
			{
				// get photo one model and setting it as this reports photo one
				this.photoOne = this.report.getPhotoOne();
				// update to display photo one
				this.photoOneDisplay();
			}
			// check if the report model has a photo two model attached
			if (this.report.getPhotoTwo().getId() > -1)
			{
				// get photo two model and setting it as this reports photo two
				this.photoTwo = this.report.getPhotoTwo();
				// update to display photo two
				this.photoTwoDisplay();
			}
			// check if the report model has a photo three model attached
			if (this.report.getPhotoThree().getId() > -1)
			{
				// get photo three model and setting it as this reports photo three
				this.photoThree = this.report.getPhotoThree();
				// update to display photo three
				this.photoThreeDisplay();
			}
			
			// get the names from the report and set them as the mushroom names
			this.family = this.report.getFamily();
			this.genus = this.report.getGenus();
			this.species = this.report.getSpecies();
			// names have changed so update name selection buttons
			this.updateSelections();
			
			// get the report note text and set the notes body to that text
			this.aq.id(R.id.notesBody).text(this.report.getNote());
			
		}
        else
        {
	        // try to get the family name from the intent bundle incase we are coming from the field guide
	        String family = this.getIntent().getStringExtra(FAMILY_NAME);
	        // check if got a family name
	        if (family != null)
	        {
	        	// set the family name for this report
	        	this.family = family;
	        	
	        	// try to get the genus name incase the field guide sent that as well
	        	String genus = this.getIntent().getStringExtra(GENUS_NAME);
	        	// check if got the genus name
	        	if (genus != null)
	        	{
	        		// set the genus name for this report
	        		this.genus = genus;
	        		
	        		// try to get the species name incase the field guide sent that as well
	        		String species = this.getIntent().getStringExtra(SPECIES_NAME);
	        		// check if got the species name
	            	if (species != null)
	            	{
	            		// set the species name for this report
	            		this.species = species;
	            	}
	        	}
	        	// we got at least the family name so update the selection buttons to display the new names
	        	this.updateSelections();
	        }
        }
        
        // attach handlers for the photo buttons
        aq.id(R.id.topPicButton).clicked(this, "photoOneClicked");
        aq.id(R.id.sidePicButton).clicked(this, "photoTwoClicked");
        aq.id(R.id.bottomPicButton).clicked(this, "photoThreeClicked");
        
        // attach handlers for the selection buttons
        aq.id(R.id.familySelectionButton).clicked(this, "familySelection");
        aq.id(R.id.familySelectionClearButton).clicked(this, "familyClear");
        aq.id(R.id.genusSelectionButton).clicked(this, "genusSelection");
        aq.id(R.id.genusSelectionClearButton).clicked(this, "genusClear");
        aq.id(R.id.speciesSelectionButton).clicked(this, "speciesSelection");
    	aq.id(R.id.speciesSelectionClearButton).clicked(this, "speciesClear");
        
    	// check if the species is Unknown
        if (this.species == "Unknown")
        {
        	// disable the selection and clear buttons
        	aq.id(R.id.speciesSelectionButton).enabled(false);
        	aq.id(R.id.speciesSelectionClearButton).enabled(false);
        }
        
        // attach handlers for the rest of the buttons
        aq.id(R.id.fieldGuideButton).clicked(this, "viewFieldGuide");
        aq.id(R.id.notesHeader).clicked(this, "toggleNotes");
        aq.id(R.id.cancelButton).clicked(this, "cancel");
        aq.id(R.id.saveButton).clicked(this, "saveClicked");
    }
	
	/**
	 * Find Activity resume handler
	 * 
	 * @param   void
	 * @return	void
	 */
	@Override
	public void onResume()
	{
		super.onResume();
		
		try 
		{
			// resume the GPS service connection
			this.gps.resume(this);
		} 
		catch (GPSNotAvailable e) 
		{
			// when GPS is not available for resume
			e.printStackTrace();
		}
	}
	
	/**
	 * Find Activity pause handler
	 * 
	 * @param   void
	 * @return	void
	 */
	@Override
	protected void onPause() 
	{
		super.onPause();
		
		// pause the gps service connection
		this.gps.pause(this);
	}
	
	/**
	 * Find Activity activity result handler
	 * is called when a response is received from 
	 * an activity we have launched for a response
	 * like the name select activity and the photo
	 * activity
	 * 
	 * @param   requestCode - int - The integer request code originally supplied to startActivityForResult(), allowing you to identify who this result came from.
	 * @param	resultCode - int - The integer result code returned by the child activity through its setResult().
	 * @param	data  - Intent - An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
	 * @return	void
	 */
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) 
	{
		// Check first to make sure the activity launched successfully got a result
		if (resultCode == RESULT_OK) 
		{
			// Switch over the different types of requests we make from this activity
			// so we know how to handle the result of that request
			switch (requestCode)
			{
				// if we got a family name from the name select activity
				case RESULT_TYPE_FAMILY:
					// get the family name from the result data and set the report family name to it
					this.family = data.getStringExtra(NameSelectActivity.RESULT_NAME);
					
					// if the family name was not returned
					if (this.family == null)
					{
						// set the report family to Unknown
						this.family = "Unknown";
					}
					
					// the family name for this report has changed update the selection buttons
					this.updateSelections();
					
				break;
				// if we got a genus name from the name select activity
				case RESULT_TYPE_GENUS:
					// get the genus name from the result data and set the report genus name to it
					this.genus = data.getStringExtra(NameSelectActivity.RESULT_NAME);
					
					// if the genus name was not returned
					if (this.genus == null)
					{
						// set the report genus to Unknown
						this.genus = "Unknown";
					}
					
					// the genus name for this report has changed update the selection buttons
					this.updateSelections();
					
				break;
				// if we got a species name from the name select activity
				case RESULT_TYPE_SPECIES:
					// get the species name from the result data and set the report species name to it
					this.species = data.getStringExtra(NameSelectActivity.RESULT_NAME);
					
					// if the species name was not returned
					if (this.species == null)
					{
						// set the report species to Unknown
						this.species = "Unknown";
					}
					
					// the species name for this report has changed update the selection buttons
					this.updateSelections();
					
				break;
				// if we got a new image from the photo activity
				case RESULT_TYPE_IMAGE_GET:
					// get the new id of the image model from the photo activity data
					long imageId = data.getLongExtra(ModelImage.IMAGE_ID, -1);
					
					// check to make sure that we got the image id
					if (imageId > -1)
					{
						// get and switch over the photo number to update the correct photo
						switch (data.getIntExtra(PhotoActivity.PHOTO_NUM, -1)) 
						{
							case PhotoActivity.PHOTO_ONE:
								// find and set this reports photo one model to the new image model
								this.photoOne = new ModelImage(this, imageId).find();
								// update the display of photo one
								this.photoOneDisplay();
							break;
							case PhotoActivity.PHOTO_TWO:
								// find and set this reports photo two model to the new image model
								this.photoTwo = new ModelImage(this, imageId).find();
								// update the display of photo two
								this.photoTwoDisplay();
							break;
							case PhotoActivity.PHOTO_THREE:
								// find and set this reports photo three model to the new image model
								this.photoThree = new ModelImage(this, imageId).find();
								// update the display of photo three
								this.photoThreeDisplay();
							break;
						}
					}
					
				break;
				// if we got a photo delete from the name photo activity
				case RESULT_TYPE_IMAGE_DELETE:
					// get and switch over the photo number to figure out which photo to delete
					switch (data.getIntExtra(PhotoActivity.PHOTO_NUM, -1)) 
					{
						case PhotoActivity.PHOTO_ONE:
							// clear photo one
							this.photoOneClear();
						break;
						case PhotoActivity.PHOTO_TWO:
							// clear photo two
							this.photoTwoClear();
						break;
						case PhotoActivity.PHOTO_THREE:
							// clear photo three
							this.photoThreeClear();
						break;
					}
					
				break;
			}
		}
	}
	
	/**
	 * Called when the family selection button is clicked
	 * launches the name select activity to get the new family name
	 * 
	 * @param   void
	 * @return	void
	 */
	public void familySelection()
	{
		// create an intent with the desired result type of family and launch the Name Select activity for the result type family response
		this.startActivityForResult(new Intent(this, NameSelectActivity.class).putExtra(NameSelectActivity.RESULT_TYPE, RESULT_TYPE_FAMILY), RESULT_TYPE_FAMILY);
	}
	
	/**
	 * Called when the family clear button is clicked
	 * clears the current family from the report
	 * 
	 * @param   void
	 * @return	void
	 */
	public void familyClear()
	{
		// set the report family to Unknown
		this.family = "Unknown";
		// since we don't know the family we can't know the genus so clear the genus as well
		this.genusClear();
	}
	
	/**
	 * Called when the genus selection button is clicked
	 * launches the name select activity to get the new genus name
	 * 
	 * @param   void
	 * @return	void
	 */
	public void genusSelection()
	{
		// create an intent for the Name Select Activity passing the requested result type as genus
		Intent intent = new Intent(this, NameSelectActivity.class).putExtra(NameSelectActivity.RESULT_TYPE, RESULT_TYPE_GENUS);
		// check if the family is known
		if (this.family != "Unknown")
		{
			// add to the intent the id of the family model found for the family name attached to this find
			intent.putExtra(ModelFamily.FAMILY_ID, new ModelFamily(this).find(this.family).getId());
		}
		// start the Name Select Activity for result type genus
		this.startActivityForResult(intent, RESULT_TYPE_GENUS);
	}
	
	/**
	 * Called when the genus clear button is clicked
	 * clears the current genus from the report
	 * 
	 * @param   void
	 * @return	void
	 */
	public void genusClear()
	{
		// set the report genus to Unknown
		this.genus = "Unknown";
		// since we don't know the genus we can't know the species so clear the species as well
		this.speciesClear();
	}
	
	/**
	 * Called when the species selection button is clicked
	 * launches the name select activity to get the new species name
	 * 
	 * @param   void
	 * @return	void
	 */
	public void speciesSelection()
	{
		// create an intent for the Name Select Activity passing the requested result type as species
		Intent intent = new Intent(this, NameSelectActivity.class).putExtra(NameSelectActivity.RESULT_TYPE, RESULT_TYPE_SPECIES);
		// check if the genus is known
		if (this.genus != "Unknown")
		{
			// add to the intent the id of the genus model found for the genus name attached to this find
			intent.putExtra(ModelGenus.GENUS_ID, new ModelGenus(this).find(this.genus).getId());
		}
		// start the Name Select Activity for result type species
		this.startActivityForResult(intent, RESULT_TYPE_SPECIES);
	}
	
	/**
	 * Called when the species clear button is clicked
	 * clears the current species from the report
	 * 
	 * @param   void
	 * @return	void
	 */
	public void speciesClear()
	{
		// set the report species to Unknown
		this.species = "Unknown";
		// update the displayed name selections
		this.updateSelections();
	}
	
	/**
	 * Called when the species clear button is clicked
	 * clears the current species from the report
	 * 
	 * @param   void
	 * @return	void
	 */
	public void updateSelections()
	{
		// set the species selection button text to the current species name
		this.aq.id(R.id.speciesSelectionButton).text(this.species);
		// check to see if the current species is known and the current genus is not
		if (this.species != "Unknown" && this.genus == "Unknown")
		{
			// find the model for the current species name and get the model genus for that species
			// then get the genus name from that genus model
			this.genus = new ModelSpecies(this).find(this.species).getGenus().getName();
		}
		
		// set the genus selection button text to the current genus name
		this.aq.id(R.id.genusSelectionButton).text(this.genus);
		// check to see if the current genus is known
		if (this.genus != "Unknown")
		{
			// we know the genus so enable the species selection and clear buttons
			this.aq.id(R.id.speciesSelectionButton).enabled(true);
			this.aq.id(R.id.speciesSelectionClearButton).enabled(true);
			
			// check to see if family is unknown
			if (this.family == "Unknown")
			{
				// find the model for the current genus name and get the model family for that genus
				// then get the family name from that family model
				this.family = new ModelGenus(this).find(this.genus).getFamily().getName();
			}
		}
		else
		{
			// since we do not know the genus disable the species selection and clear buttons
			this.aq.id(R.id.speciesSelectionButton).enabled(false);
			this.aq.id(R.id.speciesSelectionClearButton).enabled(false);
		}
		
		// set the genus selection button text to the current family name
		this.aq.id(R.id.familySelectionButton).text(family);
	}
	
	/**
	 * Called when photo one is clicked launches
	 * the Photo Activity to add, view or delete
	 * photo one
	 * 
	 * @param   void
	 * @return	void
	 */
	public void photoOneClicked()
	{
		// create an intent for the Photo activity and put the photo num as one
		Intent intent = new Intent(this, PhotoActivity.class).putExtra(PhotoActivity.PHOTO_NUM, PhotoActivity.PHOTO_ONE);
		
		// check if we currently have a photo one attached to this report
		if (this.photoOne == null)
		{
			// put into the intent that the desired result type is image get
			intent.putExtra(PhotoActivity.RESULT_TYPE, RESULT_TYPE_IMAGE_GET);
			// launch the photo activity for the image get result
			this.startActivityForResult(intent, RESULT_TYPE_IMAGE_GET);
		}
		else
		{
			// put into the intent that the desired result type is image delete 
			// (if photo is just viewed the photo activity will simply return result canceled
			intent.putExtra(PhotoActivity.RESULT_TYPE, RESULT_TYPE_IMAGE_DELETE);
			// put into the intent the id of photo one
			intent.putExtra(ModelImage.IMAGE_ID, this.photoOne.getId());
			// launch the photo activity for the image delete result
			this.startActivityForResult(intent, RESULT_TYPE_IMAGE_DELETE);
		}
	}
	
	/**
	 * Update the photo one button to show the
	 * current photo one attached to the report
	 * 
	 * @param   void
	 * @return	void
	 */
	public void photoOneDisplay()
	{
		// get the pic one button view and get the the width of that view
		int width = aq.id(R.id.topPicButton).getView().getWidth();
		// check that got width
		if (width == 0)
		{
			// default to 100
			width = 100;
		}
		// get the pic one button and set the image to the image one path
		// cache the image in file and memory at the width of the button view
		aq.id(R.id.topPicButton).image(this.photoOne.getPath(), true, true, width, 0);
	}
	
	/**
	 * Clear the photo one button to display no photo
	 * 
	 * @param   void
	 * @return	void
	 */
	public void photoOneClear()
	{
		// set the photo one model to null
		this.photoOne = null;
		// set the pic one button image to android menu camara image
		aq.id(R.id.topPicButton).image(android.R.drawable.ic_menu_camera);
	}
	
	/**
	 * Called when photo two is clicked launches
	 * the Photo Activity to add, view or delete
	 * photo two
	 * 
	 * @param   void
	 * @return	void
	 */
	public void photoTwoClicked()
	{
		// create an intent for the Photo activity and put the photo num as two
		Intent intent = new Intent(this, PhotoActivity.class).putExtra(PhotoActivity.PHOTO_NUM, PhotoActivity.PHOTO_TWO);
		
		// check if we currently have a photo two attached to this report
		if (this.photoTwo == null)
		{
			// put into the intent that the desired result type is image get
			intent.putExtra(PhotoActivity.RESULT_TYPE, RESULT_TYPE_IMAGE_GET);
			// launch the photo activity for the image get result
			this.startActivityForResult(intent, RESULT_TYPE_IMAGE_GET);
		}
		else
		{
			// put into the intent that the desired result type is image delete 
			// (if photo is just viewed the photo activity will simply return result canceled
			intent.putExtra(PhotoActivity.RESULT_TYPE, RESULT_TYPE_IMAGE_DELETE);
			// put into the intent the id of photo two
			intent.putExtra(ModelImage.IMAGE_ID, this.photoTwo.getId());
			// launch the photo activity for the image delete result
			this.startActivityForResult(intent, RESULT_TYPE_IMAGE_DELETE);
		}
	}
	
	/**
	 * Update the photo two button to show the
	 * current photo two attached to the report
	 * 
	 * @param   void
	 * @return	void
	 */
	public void photoTwoDisplay()
	{
		// get the pic two button view and get the the width of that view
		int width = aq.id(R.id.sidePicButton).getView().getWidth();
		// check that got width
		if (width == 0)
		{
			// default to 100
			width = 100;
		}
		// get the pic two button and set the image to the image two path
		// cache the image in file and memory at the width of the button view
		aq.id(R.id.sidePicButton).image(this.photoTwo.getPath(), true, true, width, 0);
	}
	
	/**
	 * Clear the photo two button to display no photo
	 * 
	 * @param   void
	 * @return	void
	 */
	public void photoTwoClear()
	{
		// set the photo two model to null
		this.photoTwo = null;
		// set the pic two button image to android menu camara image
		aq.id(R.id.sidePicButton).image(android.R.drawable.ic_menu_camera);
	}
	
	/**
	 * Called when photo three is clicked launches
	 * the Photo Activity to add, view or delete
	 * photo three
	 * 
	 * @param   void
	 * @return	void
	 */
	public void photoThreeClicked()
	{
		// create an intent for the Photo activity and put the photo num as two
		Intent intent = new Intent(this, PhotoActivity.class).putExtra(PhotoActivity.PHOTO_NUM, PhotoActivity.PHOTO_THREE);
		
		// check if we currently have a photo three attached to this report
		if (this.photoThree == null)
		{
			// put into the intent that the desired result type is image get
			intent.putExtra(PhotoActivity.RESULT_TYPE, RESULT_TYPE_IMAGE_GET);
			// launch the photo activity for the image get result
			this.startActivityForResult(intent, RESULT_TYPE_IMAGE_GET);
		}
		else
		{
			// put into the intent that the desired result type is image delete 
			// (if photo is just viewed the photo activity will simply return result canceled
			intent.putExtra(PhotoActivity.RESULT_TYPE, RESULT_TYPE_IMAGE_DELETE);
			// put into the intent the id of photo three
			intent.putExtra(ModelImage.IMAGE_ID, this.photoThree.getId());
			// launch the photo activity for the image delete result
			this.startActivityForResult(intent, RESULT_TYPE_IMAGE_DELETE);
		}
	}
	
	/**
	 * Update the photo three button to show the
	 * current photo three attached to the report
	 * 
	 * @param   void
	 * @return	void
	 */
	public void photoThreeDisplay()
	{
		// get the pic three button view and get the the width of that view
		int width = aq.id(R.id.bottomPicButton).getView().getWidth();
		// check that got width
		if (width == 0)
		{
			// default to 100
			width = 100;
		}
		// get the pic three button and set the image to the image two path
		// cache the image in file and memory at the width of the button view
		aq.id(R.id.bottomPicButton).image(this.photoThree.getPath(), true, true, width, 0);
	}
	
	/**
	 * Clear the photo three button to display no photo
	 * 
	 * @param   void
	 * @return	void
	 */
	public void photoThreeClear()
	{
		// set the photo three model to null
		this.photoThree = null;
		// set the pic three button image to android menu camara image
		aq.id(R.id.bottomPicButton).image(android.R.drawable.ic_menu_camera);
	}
	
	/**
	 * onClick Handler for cancel button
	 * 
	 * @param   void
	 * @return	void
	 */
	public void cancel()
	{
		// check to make sure we are not editing a current report
		if (this.report == null)
		{
			// check if we have photo one on this report
			if (this.photoOne != null)
			{
				// delete photo one from the file system
				this.photoOne.getFile().delete();
				// delete photo one from the db
				this.photoOne.delete();
			}
			// check if we have photo two on this report
			if (this.photoTwo != null)
			{
				// delete photo two from the file system
				this.photoTwo.getFile().delete();
				// delete photo two from the db
				this.photoTwo.delete();
			}
			// check if we have photo three on this report
			if (this.photoThree != null)
			{
				// delete photo three from the file system
				this.photoThree.getFile().delete();
				// delete photo three from the db
				this.photoThree.delete();
			}
		}
		
		// end this activity
		this.finish();
	}
	
	/**
	 * onClick Handler for save button
	 * 
	 * @param   void
	 * @return	void
	 */
	public void saveClicked()
	{
		// check if the report does not exist so this a new report
		if (this.report == null)
		{
			// create new report model and assign it to this finds report
			this.report = new ModelReport(this);
			// set the report date to the current date-time
			this.report.setDate(Calendar.getInstance().getTime());
			// show the location dialog to inform the user we are gettin the current location
			this.locationDialog.show(this.getSupportFragmentManager(), "dialog");
			// create a new location request callback and use it to request a new location from the GPS
			this.gps.requestLocation(new LocationRequest());
		}
		else
		{
			// since we already have a report go strait to saving the changes
			this.save();
		}
	}

	/**
	 * Saves the current location for the report. Is called by the LocationRequest class when
	 * it gets a location from the GPS
	 * 
	 * @param   location - Location - the location to save to the report
	 * @return	void
	 */
	public void saveLocation(Location location)
	{
		// dismiss the location dialog as report now has a location
		this.locationDialog.dismiss();
		
		// set the report long and lat to that of the new location
		this.report.setLatitude(location.getLatitude());
		this.report.setLongitude(location.getLongitude());
		
		// save the report data
		this.save();
	}
	
	/**
	 * onClick Handler if the user clicks save without location
	 * on the location dialog
	 * 
	 * @param   void
	 * @return	void
	 */
	public void saveWithoutClicked()
	{
		// tell the gps to cancel the current location request
		this.gps.cancelRequst();
		// dismiss the location dialog as no longer looking for a location
		this.locationDialog.dismiss();
		
		// save the report data
		this.save();
	}
	
	/**
	 * Saves the current report data for new or edited report
	 * 
	 * @param   void
	 * @return	void
	 */
	public void save()
	{
		// set on the report model the names for this mushroom
		this.report.setFamily(this.family);
		this.report.setGenus(this.genus);
		this.report.setSpecies(this.species);
		// get the note text and attach that as the report note
		this.report.setNote(this.aq.id(R.id.notesText).getText()+"");
		// save the report model to the db
		this.report.save();
		
		// check if there is a photo one for this report
		if (this.photoOne != null)
		{
			// attach this report model to the photo one model
			this.photoOne.setReport(this.report);
			// save photo one model
			this.photoOne.save();
			// attach the photo to the report
			this.report.setPhotoOne(photoOne);
		}
		// check if there is a photo two for this report
		if (this.photoTwo != null)
		{
			// attach this report model to the photo two model
			this.photoTwo.setReport(this.report);
			// save photo two model
			this.photoTwo.save();
			// attach the photo to the report
			this.report.setPhotoTwo(photoTwo);
		}
		// check if there is a photo three for this report
		if (this.photoThree != null)
		{
			// attach this report model to the photo three model
			this.photoThree.setReport(this.report);
			// save photo three model
			this.photoThree.save();
			// attach the photo to the report
			this.report.setPhotoThree(photoThree);
		}
		
		// report is saved so end the find activity
		this.finish();
	}
	
	/**
	 * onClick activity for the Field Guide button.
	 * 
	 * @param void
	 */
	public void viewFieldGuide()
	{
		// start the Field Guide Activity
		this.startActivity(new Intent(this, FieldGuideActivity.class));
	}
	
	/**
	 * onClick activity for the notes toggle
	 * shows and hides the notes text
	 * 
	 * @param void
	 */
	public void toggleNotes() 
	{
		// get the view for the notes body
		View notesBody = aq.id(R.id.notesBody).getView();
		
		// check if notes body is not showing
		if (notesBody.getVisibility() == View.GONE) 
		{
			// make the notes body visible
			notesBody.setVisibility(View.VISIBLE);
			// change the notes expand icon to android ic input delete
			aq.id(R.id.notesExpandIcon).image(android.R.drawable.ic_input_delete);
		} 
		else 
		{
			// make the notes body invisible and remove its space on the screen
			notesBody.setVisibility(View.GONE);
			// change the notes expand icon to android ic input add
			aq.id(R.id.notesExpandIcon).image(android.R.drawable.ic_input_add);
		}
	}

}
